package com.teamsun.rptcfg;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.teamsun.entity.TableHeader;
import com.teamsun.exception.ServiceException;
import com.teamsun.util.CommonUtils;
import com.teamsun.util.Constants;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * <p>解析报表配置文件</p>
 */
public class ParseRptCfg{

    /**
     * 解析报表配置文件
     * @param inputStream 报表配置文件输入流
     * @param fileName 文件名
     * @return
     */
    public BaseRpt parseRptCfg(InputStream inputStream, String fileName) {
        BaseRpt simpleRpt = new BaseRpt();
        try {
            simpleRpt.setResetHeader(false);

            // 读取报表配置文件
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(inputStream);
            Element report = document.getRootElement();

            // 是否需要显示查询条件
            Attribute needQueryAttr = report.attribute("needQuery");
            if(needQueryAttr != null) {
                String needQuery = needQueryAttr.getValue();
                if(StringUtils.isNotBlank(needQuery)) {
                    simpleRpt.setNeedQuery(needQuery);
                } else {
                    simpleRpt.setNeedQuery(Constants.YES);
                }
            } else {
                // 如果未配置则默认显示查询条件
                simpleRpt.setNeedQuery(Constants.YES);
            }

            // 报表是否需要汇总
            Attribute needSumAttr = report.attribute("needSum");
            if(needSumAttr != null) {
                String needSum = needSumAttr.getValue();
                if(StringUtils.isNotBlank(needSum)) {
                    simpleRpt.setNeedSum(needSum);
                } else {
                    simpleRpt.setNeedSum(Constants.NO);
                }
            } else {
                // 如果未配置则默认不需要汇总
                simpleRpt.setNeedSum(Constants.NO);
            }

            // 报表是否需要分页
            Attribute needPageAttr = report.attribute("needPage");
            if(needPageAttr != null) {
                String needPage = needPageAttr.getValue();
                if(StringUtils.isNotBlank(needPage)) {
                    simpleRpt.setNeedPage(needPage);
                } else {
                    simpleRpt.setNeedPage(Constants.NO);
                }
            } else {
                // 如果未配置则默认不分页
                simpleRpt.setNeedPage(Constants.NO);
            }

            // 报表是否需要导出
            Attribute needImportAttr = report.attribute("needImport");
            if(needImportAttr != null) {
                String needImport = needImportAttr.getValue();
                if(StringUtils.isNotBlank(needImport)) {
                    simpleRpt.setNeedImport(needImport);
                } else {
                    simpleRpt.setNeedImport(Constants.YES);
                }
            } else {
                // 如果未配置则默认需要导出
                simpleRpt.setNeedImport(Constants.YES);
            }

            // 报表是否需要离线下载
            Attribute offLineAttr = report.attribute("needOffLine");
            if(offLineAttr != null) {
                String needOffLine = offLineAttr.getValue();
                if(StringUtils.isNotBlank(needOffLine)) {
                    simpleRpt.setNeedOffLine(needOffLine);
                } else {
                    // 默认不要用离线下载
                    simpleRpt.setNeedOffLine(Constants.NO);
                }
            } else {
                // 默认不要用离线下载
                simpleRpt.setNeedOffLine(Constants.NO);
            }

            // 报表是否有左侧分析菜单
            Attribute needAnalysisAttr = report.attribute("needAnalysis");
            if(needAnalysisAttr != null) {
                String needAnalysis = needAnalysisAttr.getValue();
                if(StringUtils.isNotBlank(needAnalysis)) {
                    simpleRpt.setNeedAnalysis(needAnalysis);
                } else {
                    simpleRpt.setNeedAnalysis(Constants.NO);
                }
            } else {
                // 如果未配置默认无左侧菜单
                simpleRpt.setNeedAnalysis(Constants.NO);
            }

            // 报表页面风格
            Attribute rptStyleAttr = report.attribute("rptStyle");
            if(rptStyleAttr != null) {
                simpleRpt.setRptStyle(rptStyleAttr.getValue());
            } else {
                simpleRpt.setRptStyle("");
            }

            // 第三方传入参数
            Attribute thirdParamAttr = report.attribute("thirdParam");
            if(thirdParamAttr != null) {
                simpleRpt.setThirdParam(thirdParamAttr.getValue());
            } else {
                simpleRpt.setThirdParam("");
            }

            // 报表初始化查询参数
            Attribute initConditionAttr = report.attribute("initCondition");
            if(initConditionAttr != null) {
                simpleRpt.setInitCondition(initConditionAttr.getValue());
            } else {
                simpleRpt.setInitCondition("");
            }

            // 报表配置文件模板
            Attribute xmlTemplate = report.attribute("xmlTemplate");
            if(xmlTemplate != null) {
                simpleRpt.setXmlTemplate(rptStyleAttr.getValue());
            } else {
                simpleRpt.setXmlTemplate("");
            }

            // 报表查询模板类型
            Attribute tmplateTypeAttr = report.attribute("tmplateType");
            if(tmplateTypeAttr != null) {
                String tmplateType = tmplateTypeAttr.getValue();
                if(StringUtils.isNotBlank(tmplateType)) {
                    simpleRpt.setTmplateType(tmplateType);
                } else {
                    simpleRpt.setTmplateType(Constants.TMPLATETYPE_DEFAULT);
                }
            } else {
                simpleRpt.setTmplateType(Constants.TMPLATETYPE_DEFAULT);
            }

            // 是否隐藏查询条件
            Attribute isHideConditionAttr = report.attribute("isHideCondition");
            if(isHideConditionAttr != null) {
                String isHideCondition = isHideConditionAttr.getValue();
                if(StringUtils.isNotBlank(isHideCondition)) {
                    simpleRpt.setIsHideCondition(isHideCondition);
                }
            }

            Attribute drillLayoutAttr = report.attribute("drillLayout");
            if(drillLayoutAttr != null) {
                String drillLayout = drillLayoutAttr.getValue();
                if(StringUtils.isNotBlank(drillLayout)) {
                    simpleRpt.setDrillLayout(drillLayout);
                } else {
                    simpleRpt.setDrillLayout(Constants.NO);
                }
            } else {
                simpleRpt.setDrillLayout(Constants.NO);
            }

            // 报表是否支持自定义报表功能
            Attribute selfDefineAttr = report.attribute("selfDefine");
            if(selfDefineAttr != null) {
                String selfDefine = selfDefineAttr.getValue();
                if(StringUtils.isNotBlank(selfDefine)) {
                    simpleRpt.setSelfDefine(selfDefine);
                } else {
                    simpleRpt.setSelfDefine(Constants.NO);
                }
            } else {
                simpleRpt.setSelfDefine(Constants.NO);
            }

            // 报表是否支持导出指标卡
            Attribute idxCardAttr = report.attribute("idxCard");
            if(idxCardAttr != null) {
                String idxCard = idxCardAttr.getValue();
                if(StringUtils.isNotBlank(idxCard)) {
                    simpleRpt.setIdxCard(idxCard);
                } else {
                    simpleRpt.setIdxCard(Constants.NO);
                }
            } else {
                simpleRpt.setIdxCard(Constants.NO);
            }

            // 报表数据来源
            Element from = report.element("from");
            /*if(from == null) {
                throw new ServiceException("[" + fileName + "]报表配文件中未配置from元素");
            }
            String fromInfo = from.getText();
            if("".equals(fromInfo)) {
                throw new ServiceException("[" + fileName + "]报表配文件中from元素的内容不能为空");
            }*/

            // 对于嵌套查询，可能存在无from的情况，数据源可能配置在nestFrom中
            String fromInfo = "";
            if(from != null) {
                fromInfo = from.getText();
                simpleRpt.setFromInfo(fromInfo);
            }

            // 报表数据来源(嵌套SQL)
            Element nestFromEle = report.element("nestFrom");
            String nestSQL = "";
            List<InnerNestFrom> innerNestFromList = new ArrayList<InnerNestFrom>();
            NestFrom nestFrom = new NestFrom();
            if(nestFromEle != null) {
                Iterator<Element> innerNestFroms = nestFromEle.elementIterator("innerNestFrom");
                // 获取多级嵌套信息
                while (innerNestFroms.hasNext()) {
                    InnerNestFrom innerNestFrom = new InnerNestFrom();
                    Element innerNestFromEle = innerNestFroms.next();
                    Attribute innerLevelAttr = innerNestFromEle.attribute("innerLevel");
                    if (innerLevelAttr == null) {
                        throw new ServiceException("[" + fileName + "]报表配置中innerNestFrom元素未配置innerLevel属性");
                    }
                    String innerLevel = innerNestFromEle.attributeValue("innerLevel");
                    String innerSQL = innerNestFromEle.getText();
                    innerNestFrom.setInnerLevel(innerLevel);
                    innerNestFrom.setInnerSQL(innerSQL);
                    innerNestFromList.add(innerNestFrom);
                }
                if(innerNestFromList.size() == 0) {
                    nestSQL = nestFromEle.getText();
                    if(StringUtils.isNotBlank(nestSQL)) {
                        nestFrom.setNestSQL(nestSQL);
                    }
                } else {
                    nestFrom.setInnerNestFromList(innerNestFromList);
                }
            }
            simpleRpt.setNestFrom(nestFrom);

            if(StringUtils.isBlank(fromInfo) && StringUtils.isBlank(nestSQL) && innerNestFromList.size() == 0) {
                throw new ServiceException("[" + fileName + "]报表配文件中from、nestFrom元素的内容不能同时为空");
            }

            // 报表初始化排序
            Element orderBy = report.element("order");
            if(orderBy != null) {
                String orderByInfo = orderBy.getText();
                if (!"".equals(orderByInfo)) {
                    simpleRpt.setOrderInfo(orderByInfo);
                }
            }

            // 报表查询group by
            Iterator<Element> groutEles = report.elementIterator("group");
            Map<String, DefaultGroup> groupMap = new HashMap<String, DefaultGroup>();
            while(groutEles.hasNext()) {
                Element groupEle = groutEles.next();
                DefaultGroup defaultGroup = new DefaultGroup();
                String conditionLvl = groupEle.attributeValue("conditionLevel");
                // 如果conditionLevel未配置则默认为1
                if(StringUtils.isBlank(conditionLvl)) {
                    conditionLvl = Constants.CONDITION_LVL_MID;
                }
                defaultGroup.setConditionLevel(conditionLvl);
                String initGroup = groupEle.getText();
                if(StringUtils.isNotBlank(initGroup)) {
                    defaultGroup.setGroupTxt(initGroup);
                    // 如果group中包含rollup()函数，该函数会查出汇总数据
                    // 此时需要将报表设置为默认汇总
                    if(Constants.CONDITION_LVL_MID.equals(conditionLvl)) {
                        String ignoreCaseGroup = initGroup.toLowerCase();
                        if(ignoreCaseGroup.contains("rollup(")) {
                            simpleRpt.setDefaultSum(Constants.YES);
                        }
                    }
                }
                groupMap.put(conditionLvl, defaultGroup);
            }
            simpleRpt.setDefaultGroup(groupMap);

            // 默认查询条件
            Iterator<Element> whereEles = report.elementIterator("defaultWhere");
            Map<String, DefaultWhere> whereMap = new HashMap<String, DefaultWhere>();
            while(whereEles.hasNext()) {
                Element defaultWhereEle = whereEles.next();
                DefaultWhere defaultWhere = new DefaultWhere();
                String conditionLvl = defaultWhereEle.attributeValue("conditionLevel");
                if(StringUtils.isBlank(conditionLvl)) {
                    conditionLvl = Constants.CONDITION_LVL_MID;
                }

                defaultWhere.setConditionLevel(conditionLvl);
                String initWhere = defaultWhereEle.getText();
                Element andEle = defaultWhereEle.element("and");
                Element orEle = defaultWhereEle.element("or");
                if(StringUtils.isNotBlank(initWhere)) {
                    defaultWhere.setConditionTxt(initWhere);
                }
                if(andEle != null) {
                    String andWhere = andEle.getText();
                    defaultWhere.setAndCondition(andWhere);
                }
                if(orEle != null) {
                    String orWhere = orEle.getText();
                    defaultWhere.setOrCondition(orWhere);
                }
                whereMap.put(conditionLvl, defaultWhere);
            }
            simpleRpt.setDefaultWhere(whereMap);

            // having过滤条件
            Iterator<Element> havingEles = report.elementIterator("having");
            Map<String, Having> havingMap = new HashMap<String, Having>();
            while(havingEles.hasNext()) {
                Element havingEle = havingEles.next();
                Having having = new Having();
                String havingLvl = havingEle.attributeValue("havingLevel");
                if(StringUtils.isBlank(havingLvl)) {
                    havingLvl = Constants.CONDITION_LVL_MID;
                }

                having.setHavingLevel(havingLvl);
                String initHaving = havingEle.getText();
                if(StringUtils.isNotBlank(initHaving)) {
                    having.setHavingTxt(initHaving);
                }
                havingMap.put(havingLvl, having);
            }
            simpleRpt.setHaving(havingMap);

            getRptColumnInfo(simpleRpt, report, fileName);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("解析报表配置文件异常,请上传正确的配置文件," + e.getMessage());
        }

        return simpleRpt;
    }

    /**
     * 获取报表配置文件中的列元素信息
     * @param simpleRpt
     * @param report
     * @param fileName 文件名
     */
    private void getRptColumnInfo(BaseRpt simpleRpt, Element report, String fileName) throws Exception{
        simpleRpt.setAllIdx(Constants.YES);

        Iterator<Element> columns = report.elementIterator("column");
        // 报表中包含的所有显示列信息
        List<BaseRptColumn> rptColumns = new ArrayList<BaseRptColumn>();
        // 报表中包含的所有隐藏列信息
        List<BaseRptColumn> hiddenRptColumns = new ArrayList<BaseRptColumn>();
        // 报表中的锁定列信息
        List<BaseRptColumn> lockColumns = new ArrayList<BaseRptColumn>();
        List<TableHeader> lockHeaders = new ArrayList<TableHeader>();
        // 报表中的查询列
        List<BaseRptColumn> conditionColumns = new ArrayList<BaseRptColumn>();
        // 报表中的汇总列
        List<BaseRptColumn> sumColumns = new ArrayList<BaseRptColumn>();

        // aliasField属性的值不能重复
        List<String> aliasFieldValues = new ArrayList<String>();
        while(columns.hasNext()) {
            Element column = columns.next();
            BaseRptColumn rptColumn = new BaseRptColumn();

            setNeedColumnAttr("name", rptColumn, column, fileName, aliasFieldValues);  // 列名
            setNeedColumnAttr("field", rptColumn, column, fileName, aliasFieldValues);  // SQL查询列
            setNeedColumnAttr("aliasField", rptColumn, column, fileName, aliasFieldValues);  // SQL查询类别名
            setNeedColumnAttr("colType", rptColumn, column, fileName, aliasFieldValues);  // 列属性

            setUnNeedColumnAttr("aliasName", rptColumn, column, fileName);  // 别名
            setUnNeedColumnAttr("width", rptColumn, column, fileName); // 列长度
            setUnNeedColumnAttr("align", rptColumn, column, fileName); // 列对齐方式
            setUnNeedColumnAttr("isCondition", rptColumn, column, fileName);  // 列是否是查询条件
            setUnNeedColumnAttr("conditionType", rptColumn, column, fileName);  // 查询条件类型(查询类型详情参见Constants类中的CONDITIONTYPE_*)
            setUnNeedColumnAttr("formatter", rptColumn, column, fileName); // 如果查询条件类型是日期，用于设置页面展示日期的格式化方式
            setUnNeedColumnAttr("dbFormatter", rptColumn, column, fileName); // 如果查询条件类型是日期，用于设置数据库日期的格式化方式
            setUnNeedColumnAttr("queryType", rptColumn, column, fileName); // 查询类型(查询类型为输入框时该配置项才有意义 0-模糊查询 1-精确查询，默认模糊查询)
            setUnNeedColumnAttr("isNeed", rptColumn, column, fileName);  // 查询条件是否必输
            setUnNeedColumnAttr("isLock", rptColumn, column, fileName);  // 列是否锁定
            setUnNeedColumnAttr("isSumCol", rptColumn, column, fileName); // 列是否汇总
            setUnNeedColumnAttr("isShow", rptColumn, column, fileName); // 列是否显示
            setUnNeedColumnAttr("isDrill", rptColumn, column, fileName); // 列是否下钻
            setUnNeedColumnAttr("defaultValue", rptColumn, column, fileName);  // 查询列的默认值
            setUnNeedColumnAttr("numberFormat", rptColumn, column, fileName); // 数字格式化方式
            setUnNeedColumnAttr("isQueryColumn", rptColumn, column, fileName);  // 列是否是查询列
            setUnNeedColumnAttr("group", rptColumn, column, fileName);  // 指标分类
            setUnNeedColumnAttr("isSort", rptColumn, column, fileName);  // 列是否排序
            setUnNeedColumnAttr("isSelect", rptColumn, column, fileName);  // 维度是否选中
            setUnNeedColumnAttr("conditionLevel", rptColumn, column, fileName);  // 查询条件所属层级 0-表示查询条件属于最内层嵌套SQL
            setUnNeedColumnAttr("cascade", rptColumn, column, fileName); // 级联维度
            setUnNeedColumnAttr("isCount", rptColumn, column, fileName); // 是否是计数列
            setUnNeedColumnAttr("dynamicFormat", rptColumn, column, fileName); // 动态配置数字格式方式
            setUnNeedColumnAttr("isSQLColumn", rptColumn, column, fileName); // 是否是SQL拼接列
            setUnNeedColumnAttr("unit", rptColumn, column, fileName);  // 列单位
            setUnNeedColumnAttr("cascadeDate", rptColumn, column, fileName);  // 需动态格式化的日期参数
            setUnNeedColumnAttr("isVisibility", rptColumn, column, fileName);  // 查询条件是否在页面显示
            setUnNeedColumnAttr("cascadeCondition", rptColumn, column, fileName);  // 级联查询条件
            setUnNeedColumnAttr("isDateType", rptColumn, column, fileName);  // 列类型是否是日期类型
            setUnNeedColumnAttr("innerDim", rptColumn, column, fileName);
            setUnNeedColumnAttr("isOrOperator", rptColumn, column, fileName); // 查询条件是否是OR查询
            setUnNeedColumnAttr("relateName", rptColumn, column, fileName);  // 关联名称
            setUnNeedColumnAttr("fontColorByValue", rptColumn, column, fileName);  // 列数据显示颜色(根据指定值比较)
            setUnNeedColumnAttr("fontColorByRow", rptColumn, column, fileName);  // 列数据显示颜色(根据指列比较)
            setUnNeedColumnAttr("fontColorByRange", rptColumn, column, fileName);  //列数据显示颜色(根据指定值区间比较)
            setUnNeedColumnAttr("multiTreeMode", rptColumn, column, fileName);  // 多tab机构树选择模式

            String colType = rptColumn.getColType();
            if(Constants.YES.equals(colType)) {
                simpleRpt.setAllIdx(Constants.NO);
            }
            String columnName = rptColumn.getName();
            // 如果配置了日期或日期区间的查询条件，则必须同时配置日期的格式化方式(formatter)
            String condition = rptColumn.getConditionType();
            if(StringUtils.isNotBlank(condition)) {
                if(Constants.CONDITIONTYPE_DATE.equals(condition) || Constants.CONDITIONTYPE_DATE_RANGE.equals(condition)) {
                    String formatter = rptColumn.getFormatter();
                    if(StringUtils.isBlank(formatter)) {
                        throw new ServiceException("[" + fileName + "]报表配置column[" + columnName + "]中未配置formatter属性(日期列必须配置formatter属性)");
                    }
                }
            }

            String multiTreeMode = rptColumn.getMultiTreeMode();
            if(StringUtils.isEmpty(multiTreeMode)) {
                rptColumn.setMultiTreeMode(Constants.NO);
            }

            // 如果查询列类型为下拉框/多选下拉框，则需要解析下拉框的值
            if(Constants.CONDITIONTYPE_SELECT.equals(rptColumn.getConditionType()) || Constants.CONDITIONTYPE_MULTI_SELECT.equals(rptColumn.getConditionType())) {
                Element selectDimEle = column.element("selectDim");
                if(selectDimEle != null) {  // 下拉框的值来自于数据库
                    Attribute tableAttr = selectDimEle.attribute("table");
                    Attribute codeAttr = selectDimEle.attribute("code");
                    Attribute nameAttr = selectDimEle.attribute("name");
                    if(tableAttr == null) {
                        throw new ServiceException("[" + fileName + "]报表配置column[" + columnName + "]中selectDim元素未配置table属性");
                    }
                    if(codeAttr == null) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]selectDim元素未配置code属性");
                    }
                    if(nameAttr == null) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]selectDim元素未配置name属性");
                    }
                    SelectDim selectDim = new SelectDim();
                    selectDim.setTable(selectDimEle.attributeValue("table"));  // 表名
                    selectDim.setCode(selectDimEle.attributeValue("code"));  // 编码字段
                    selectDim.setName(selectDimEle.attributeValue("name"));  // 名称字段
                    String order = selectDimEle.attributeValue("order");  // 排序字段及排序方式
                    String selectCondition = selectDimEle.attributeValue("condition");  // 过滤条件
                    String dataSource = selectDimEle.attributeValue("dataSource");  // 数据源ID
                    if(StringUtils.isNotBlank(dataSource)) {
                        selectDim.setDataSource(dataSource);
                    }
                    if(StringUtils.isNotBlank(order)) {
                        selectDim.setOrder(order);
                    }
                    if(StringUtils.isNotBlank(selectCondition)) {
                        selectDim.setCondition(selectCondition);
                    }
                    rptColumn.setSelectDim(selectDim);
                } else {  // 下拉框的值配置在文件中配置
                    Map<String, String> option = new LinkedHashMap<String, String>();
                    Iterator<Element> selects = column.elementIterator("select");
                    while (selects.hasNext()) {
                        Element select = selects.next();
                        Attribute keyAttr = select.attribute("key");
                        Attribute valueAttr = select.attribute("value");
                        if (keyAttr == null) {
                            throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]select元素未配置key属性");
                        }
                        if (valueAttr == null) {
                            throw new ServiceException("[" + fileName + "]报表配置中columnn[" + columnName + "]select元素未配置value属性");
                        }
                        String key = select.attributeValue("key");
                        String value = select.attributeValue("value");
                        option.put(key, value);
                    }
                    rptColumn.setOptionValue(option);
                }
            }

            // 如果查询列类型为树，则需要解析相关维度表的配置
            if(Constants.CONDITIONTYPE_TREE.equals(rptColumn.getConditionType())) {
                Iterator<Element> treeDimEles = column.elementIterator("treeDim");
                if(treeDimEles != null) {
                    List<TreeDim> treeDims = new ArrayList<TreeDim>();
                    while (treeDimEles.hasNext()) {
                        Element treeDimEle = treeDimEles.next();
                        Attribute tableAttr = treeDimEle.attribute("table");
                        Attribute codeAttr = treeDimEle.attribute("code");
                        Attribute nameAttr = treeDimEle.attribute("name");
                        Attribute upcodeAttr = treeDimEle.attribute("upcode");
                        if(tableAttr == null) {
                            throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]treeDim元素未配置table属性");
                        }
                        if(codeAttr == null) {
                            throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]treeDim元素未配置code属性");
                        }
                        if(nameAttr == null) {
                            throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]treeDim元素未配置name属性");
                        }
                        if(upcodeAttr == null) {
                            throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]treeDim元素未配置upcode属性");
                        }
                        TreeDim treeDim = new TreeDim();
                        treeDim.setTable(treeDimEle.attributeValue("table"));  // 表名
                        treeDim.setCode(treeDimEle.attributeValue("code"));  // 编码字段
                        treeDim.setName(treeDimEle.attributeValue("name"));  // 名称字段
                        treeDim.setUpcode(treeDimEle.attributeValue("upcode"));  // 上级编码字段
                        String rightParam = treeDimEle.attributeValue("rightParam");  // 权限查询字段
                        String parentRightParam = treeDimEle.attributeValue("parentRightParam");  // 上级权限查询字段
                        String dataSource = treeDimEle.attributeValue("dataSource");  // 数据源ID
                        String order = treeDimEle.attributeValue("order");  // 排序字段及排序方式
                        String rootCode = treeDimEle.attributeValue("rootCode");  // 根节点编码(默认为空)
                        String needDefauleValue = treeDimEle.attributeValue("needDefauleValue");  // 置是否指定默认值
                        String needSearch = treeDimEle.attributeValue("needSearch");  // 是否需要添加搜索功能
                        String tabName = treeDimEle.attributeValue("tabName");  // tab名称
                        String rightField = treeDimEle.attributeValue("rightField");  // 权限字段
                        String parentRightField = treeDimEle.attributeValue("parentRightField");  // 权限字段

                        if(StringUtils.isNotBlank(rightParam)) {
                            treeDim.setRightParam(rightParam);
                        }
                        if(StringUtils.isNotBlank(parentRightParam)) {
                            treeDim.setParentRightParam(parentRightParam);
                        }
                        if(StringUtils.isNotBlank(dataSource)) {
                            treeDim.setDataSource(dataSource);
                        }
                        if(StringUtils.isNotBlank(order)) {
                            treeDim.setOrder(order);
                        }
                        if(StringUtils.isNotBlank(needDefauleValue)) {
                            treeDim.setNeedDefauleValue(needDefauleValue);
                        }
                        if(StringUtils.isNotBlank(rootCode)) {
                            treeDim.setRootCode(rootCode);
                        }
                        if(StringUtils.isNotBlank(tabName)) {
                            treeDim.setTabName(tabName);
                        }
                        if(StringUtils.isNotBlank(rightField)) {
                            treeDim.setRightField(rightField);
                        }
                        if(StringUtils.isNotBlank(parentRightField)) {
                            treeDim.setParentRightField(parentRightField);
                        }
                        if(StringUtils.isNotBlank(needSearch)) {
                            treeDim.setNeedSearch(needSearch);
                        } else {
                            treeDim.setNeedSearch(Constants.NO);
                        }
                        treeDims.add(treeDim);
                    }

                    rptColumn.setTreeDim(treeDims.get(0));
                    rptColumn.setTreeDims(treeDims);
                } else {
                    throw new ServiceException("[" + fileName + "]报表配置中" + rptColumn.getName() + "未配置treeDim");
                }
            }

            // 如果列需要下钻
            if(Constants.YES.equals(rptColumn.getIsDrill())) {
                Element drillEle = column.element("drill");
                if(drillEle != null) {
                    Attribute reportIdAttr = drillEle.attribute("reportId");
                    if(reportIdAttr == null) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName +"]drill元素未配置reportId属性");
                    }
                    RptDrill rptDrill = new RptDrill();
                    String drillLayout = drillEle.attributeValue("drillLayout");
                    if(StringUtils.isBlank(drillLayout)) {
                        rptDrill.setDrillLayout(Constants.NO);
                    } else {
                        rptDrill.setDrillLayout(drillLayout);
                    }
                    rptDrill.setRptId(drillEle.attributeValue("reportId"));
                    rptDrill.setParam(drillEle.attributeValue("param"));
                    rptDrill.setConditionParam(drillEle.attributeValue("conditionParam"));
                    rptColumn.setRptDrill(rptDrill);
                } else {
                    throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]未配置drill");
                }
            }

            if(Constants.YES.equals(rptColumn.getIsShow()) || StringUtils.isBlank(rptColumn.getIsShow())) {
                rptColumns.add(rptColumn);
            } else {
                hiddenRptColumns.add(rptColumn);
            }

            // 冻结列信息
            if(Constants.YES.equals(rptColumn.getIsLock())) {
                TableHeader lockHeader = new TableHeader();
                lockHeader.setField(rptColumn.getAliasField());
                lockHeader.setTitle(rptColumn.getName());
                String width = rptColumn.getWidth();
                if(StringUtils.isNotBlank(width)) {
                    lockHeader.setWidth(Integer.valueOf(width));
                }
                lockColumns.add(rptColumn);
                lockHeaders.add(lockHeader);
            }

            // 查询条件列信息
            if(Constants.YES.equals(rptColumn.getIsCondition())) {
                String conditionType = rptColumn.getConditionType();
                // 如果查询类型为日期或日期区间,计算默认值
                if(Constants.CONDITIONTYPE_DATE.equals(conditionType) || Constants.CONDITIONTYPE_DATE_RANGE.equals(conditionType)) {
                    rptColumn.setDateDefault(rptColumn.getDefaultValue());
                    CommonUtils.setDefaultDate(rptColumn);
                }

                if(Constants.CONDITIONTYPE_VALUE_RANGE.equals(conditionType)) {
                    String defaultValue = rptColumn.getDefaultValue();
                    if(StringUtils.isNotBlank(defaultValue)) {
                        if(defaultValue.contains(",")) {
                            String[] defaults = defaultValue.split(",");
                            rptColumn.setDefaultValue(defaults[0]);
                            rptColumn.setDefaultValueEnd(defaults[1]);
                        } else {
                            rptColumn.setDefaultValue(defaultValue);
                            rptColumn.setDefaultValueEnd(defaultValue);
                        }
                    }
                }
                conditionColumns.add(rptColumn);
            }

            // 汇总列信息
            if(Constants.YES.equals(rptColumn.getIsSumCol())) {
                sumColumns.add(rptColumn);
            }

            // 数字动态格式化列
            String aliasField = rptColumn.getAliasField();
            if(Constants.DYNAMICFORMAT_VALUE.equals(aliasField)) {
                simpleRpt.setDynamicNum(rptColumn);
            }

            // 日期动态格式化
            if(Constants.DYANMICFOMAT_DATE.equals(aliasField)) {
                simpleRpt.setDynamicDate(rptColumn);
            }
        }

        simpleRpt.setRptColumns(rptColumns);  // 报表显示列
        simpleRpt.setLockColumns(lockColumns);  // 报表冻结列
        simpleRpt.setConditionColumns(conditionColumns);  // 报表查询条件列
        simpleRpt.setSumColumns(sumColumns);  // 报表汇总列
        simpleRpt.setHiddenRptColumns(hiddenRptColumns);  // 报表隐藏列

        // 生成报表冻结列信息
        List<List<TableHeader>> lockHeaderList = new ArrayList<List<TableHeader>>();
        // 默认列宽(如果列宽未配置)
        int defaultWidth = 0;
        if(Constants.YES.equals(simpleRpt.getNeedAnalysis())) {
            defaultWidth = Constants.RPT_ANALYSIS_DEFAULT_WIDTH / rptColumns.size();
        } else {
            defaultWidth = Constants.RPT_DEFAULT_WIDTH / rptColumns.size();
        }
        if(lockHeaders != null &&lockHeaders.size() > 0) {
            for(TableHeader lockHeader : lockHeaders) {
                if(lockHeader.getWidth() == 0) {
                    lockHeader.setWidth(defaultWidth);
                }
            }
        }
        lockHeaderList.add(lockHeaders);
        PropertyFilter filter = new PropertyFilter() {
            @Override
            public boolean apply(Object object, String name, Object value) {
            if((name.equals("sortable") && "false".equals(String.valueOf(value))) || ((name.equals("hidden") && "false".equals(String.valueOf(value)))) || ((name.equals("colspan") && "0".equals(String.valueOf(value)))) || ((name.equals("rowspan") && "0".equals(String.valueOf(value)))) || ((name.equals("width") && "0".equals(String.valueOf(value))))) {
                return false;
            }
                return true;
            }
        };
        String lockHeaderJson = JSON.toJSONString(lockHeaderList, filter);
        simpleRpt.setRptLockHeader(lockHeaderJson);
    }

    /**
     * 设置Column非必配属性
     * @param attrName
     * @param fileName 文件名
     */
    private void setUnNeedColumnAttr(String attrName, BaseRptColumn rptColumn, Element column, String fileName) throws Exception{
        Attribute attribute = column.attribute(attrName);
        Class clazz = rptColumn.getClass();
        if(attribute != null) {
            String columnName = rptColumn.getName();
            String attrValue = attribute.getValue();
            if(StringUtils.isNotBlank(attrValue)) {

                if(Constants.COLATTR_ALIASFIELD.equals(attrName)) {
                    if(Constants.KEY_ORDER.equalsIgnoreCase(attrValue) || Constants.KEY_SORT.equalsIgnoreCase(attrValue)) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素的" + attrName + "属性值不能为关键字[" + Constants.KEY_ORDER + "|" + Constants.KEY_SORT + "]");
                    }
                }

                // 如果是列属性，则还需要判断列的宽度属性值只能配置成正整数类型
                if(Constants.COLATTR_WIDTH.equals(attrName)) {
                    Pattern pattern = Pattern.compile("^[1-9]+[0-9]*$");
                    boolean isNumber = pattern.matcher(attrValue).matches();
                    if(!isNumber) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素的" + attrName + "属性值只能配置为正整数");
                    }
                }

                // 如果配置了动态格式化方式，则需要判断dynamicFormat="formatType"或dynamicFormat="dateType"
                if(Constants.COLATTR_DYNAMICFORMAT.equals(attrName)) {
                    if(!Constants.DYNAMICFORMAT_VALUE.equals(attrValue) && !Constants.DYANMICFOMAT_DATE.equals(attrValue)) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素的" + attrName + "属性值只能是" + Constants.DYNAMICFORMAT_VALUE + "或" + Constants.DYANMICFOMAT_DATE);
                    }
                }

                Field field = clazz.getDeclaredField(attrName);
                field.setAccessible(true);
                field.set(rptColumn, attrValue);
            } else {
                throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素的" + attrName + "属性值不能为空");
            }
        }
    }

    /**
     * 设置Column必配属性
     * @param attrName 属性名
     * @param rptColumn 列对象
     * @param column 列元素
     * @param fileName 文件名
     * @throws Exception
     */
    private void setNeedColumnAttr (String attrName, BaseRptColumn rptColumn, Element column, String fileName, List<String> aliasFieldValues) throws Exception {
        Attribute attribute = column.attribute(attrName);
        Class clazz = rptColumn.getClass();
        String columnName = rptColumn.getName();
        if(attribute != null) {
            String attrValue = attribute.getValue();
            if(StringUtils.isNotBlank(attrValue)) {
                if(Constants.COLATTR_ALIASFIELD.equals(attrName)) {
                    if(Constants.KEY_ORDER.equalsIgnoreCase(attrValue) || Constants.KEY_SORT.equalsIgnoreCase(attrValue)) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素的" + attrName + "属性值不能为关键字[" + Constants.KEY_ORDER + "|" + Constants.KEY_SORT + "]");
                    }
                    if(aliasFieldValues.contains(attrValue)) {
                        throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素的" + attrName + "属性值[" + attrValue + "]重复");
                    }
                }
                Field field = clazz.getDeclaredField(attrName);
                field.setAccessible(true);
                field.set(rptColumn, attrValue);
            } else {
                throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素的" + attrName + "属性值不能为空");
            }
        } else {
            throw new ServiceException("[" + fileName + "]报表配置中column[" + columnName + "]元素未配置" + attrName + "属性");
        }
    }
}
